#ifndef JSHAREDDATAPOINT_H
#define JSHAREDDATAPOINT_H

#if 0 // 写时拷贝（已淘汰：被C++11的移动拷贝取代）

#include <JXQGlobal>
#include <atomic>

namespace JXQ
{

class JSharedData
{
public:
	inline JSharedData() noexcept :
		m_counter(0) {}

	inline JSharedData(const JSharedData&) noexcept :
		m_counter(0) {}

	// 使用赋值操作符会导致引用计数被破坏
	JSharedData &operator=(const JSharedData &) = delete;

	mutable std::atomic_int m_counter;
};

template <class T>
class JSharedDataPointer
{
public:
	typedef T Type;
	typedef T *pointer;

	inline void detach()
	{ if(d && d->m_counter != 1) detach_helper(); }

	inline T &operator*() { detach(); return *d; }

	inline const T &operator*() const { return *d; }

	inline T *operator->() { detach(); return d; }

	inline const T *operator->() const { return d; }

	inline operator T *() { detach(); return d; }

	inline operator const T *() const { return d; }

	inline T *data() { detach(); return d; }

	inline const T *data() const { return d; }

	inline const T *constData() const { return d; }

	inline bool operator==(const JSharedDataPointer<T> &other) const
	{ return d == other.d; }

	inline bool operator!=(const JSharedDataPointer<T> &other) const
	{ return d != other.d; }

	inline JSharedDataPointer() { d = nullptr; }
	inline ~JSharedDataPointer() { if(d && !--d->m_counter) delete d; }

	explicit JSharedDataPointer(T *data) noexcept;

	inline JSharedDataPointer(const JSharedDataPointer<T> &o) :
		d(o.d) { if(d) --d->m_counter; }

	inline JSharedDataPointer<T> &operator=(const JSharedDataPointer<T> &o)
	{
		if( o.d != d )
		{
			if( o.d )
				++o.d->m_counter;
			T *old = d;
			d = o.d;
			if( old && !--old->m_counter )
				delete old;
		}
		return *this;
	}

	inline JSharedDataPointer &operator=(T *o)
	{
		if( o != d )
		{
			if( o )
				++o->m_counter;
			T *old = d;
			d = o;
			if( old && !--old->m_counter )
				delete old;
		}
		return *this;
	}

	JSharedDataPointer(JSharedDataPointer &&o) noexcept :
		d(o.d) { o.d = nullptr; }

	inline JSharedDataPointer<T> &operator=(JSharedDataPointer<T> &&other) noexcept
	{
		JSharedDataPointer moved(std::move(other));
		std::swap(moved);
		return *this;
	}

	inline void swap(JSharedDataPointer &other) noexcept
	{ std::swap(d, other.d); }

	inline bool operator!() const { return !d; }

protected:
	T *clone();

private:
	void detach_helper();
	T *d;
};

template <class T> inline bool operator==
(std::nullptr_t p1, const JSharedDataPointer<T> &p2)
{ J_UNUSED(p1); return !p2; }

template <class T> inline bool operator==
(const JSharedDataPointer<T> &p1, std::nullptr_t p2)
{ J_UNUSED(p2); return !p1; }

template <class T>
class JExplicitlySharedDataPointer
{
public:
	typedef T Type;
	typedef T *pointer;

	inline T &operator*() const { return *d; }

	inline T *operator->() { return d; }

	inline T *operator->() const { return d; }

	inline T *data() const { return d; }

	inline const T *constData() const { return d; }

	inline T *take() { T *x = d; d = nullptr; return x; }

	inline void detach() { if(d && d->m_counter != 1) detach_helper(); }

	inline void reset()
	{
		if( d && !--d->m_counter )
			delete d;
		d = nullptr;
	}

	inline operator bool () const { return d != nullptr; }

	inline bool operator==(const JExplicitlySharedDataPointer<T> &other) const
	{ return d == other.d; }

	inline bool operator!=(const JExplicitlySharedDataPointer<T> &other) const
	{ return d != other.d; }

	inline bool operator==(const T *ptr) const { return d == ptr; }

	inline bool operator!=(const T *ptr) const { return d != ptr; }

	inline JExplicitlySharedDataPointer() { d = nullptr; }

	inline ~JExplicitlySharedDataPointer() { if(d && !--d->m_counter) delete d; }

	explicit JExplicitlySharedDataPointer(T *data) noexcept;

	inline JExplicitlySharedDataPointer(const JExplicitlySharedDataPointer<T> &o) :
		d(o.d) { if(d) ++d->m_counter; }

	template<class X>
	inline JExplicitlySharedDataPointer(const JExplicitlySharedDataPointer<X> &o)
		: d(o.data()) { if(d) ++d->m_counter; }

	inline JExplicitlySharedDataPointer<T> &operator=
	(const JExplicitlySharedDataPointer<T> &o)
	{
		if( o.d != d )
		{
			if( o.d )
				++o.d->m_counter;
			T *old = d;
			d = o.d;
			if( old && !--old->m_counter )
				delete old;
		}
		return *this;
	}

	inline JExplicitlySharedDataPointer &operator=(T *o)
	{
		if( o != d )
		{
			if( o )
				++o->m_counter;
			T *old = d;
			d = o;
			if( old && !--old->m_counter )
				delete old;
		}
		return *this;
	}

	inline JExplicitlySharedDataPointer(JExplicitlySharedDataPointer &&o) noexcept :
		d(o.d) { o.d = nullptr; }

	inline JExplicitlySharedDataPointer<T> &operator=
	(JExplicitlySharedDataPointer<T> &&other) noexcept
	{
		JExplicitlySharedDataPointer moved(std::move(other));
		swap(moved);
		return *this;
	}

	inline void swap(JExplicitlySharedDataPointer &other) noexcept
	{ std::swap(d, other.d); }

	inline bool operator!() const { return !d; }

protected:
	T *clone();

private:
	void detach_helper();
	T *d;
};

template <class T>
inline JSharedDataPointer<T>::JSharedDataPointer(T *adata) noexcept
	: d(adata) { if(d) ++d->m_counter; }

template <class T>
inline T *JSharedDataPointer<T>::clone()
{ return new T(*d); }

template <class T>
void JSharedDataPointer<T>::detach_helper()
{
	T *x = clone();
	++x->m_counter;
	if( !--d->m_counter )
		delete d;
	d = x;
}

template <class T>
inline T *JExplicitlySharedDataPointer<T>::clone()
{ return new T(*d); }

template <class T>
void JExplicitlySharedDataPointer<T>::detach_helper()
{
	T *x = clone();
	++x->m_counter;
	if( !--d->m_counter )
		delete d;
	d = x;
}

template <class T>
inline JExplicitlySharedDataPointer<T>::JExplicitlySharedDataPointer(T *adata) noexcept
	: d(adata) { if(d) ++d->m_counter; }

template <class T> inline bool operator==(std::nullptr_t p1, const JExplicitlySharedDataPointer<T> &p2)
{ J_UNUSED(p1); return !p2; }

template <class T> inline bool operator==(const JExplicitlySharedDataPointer<T> &p1, std::nullptr_t p2)
{ J_UNUSED(p2); return !p1; }

}  //namespace JXQ

#else
# waring "Obsolete: replaced by std c++11 'move copy'"
#endif //已淘汰：被C++11的移动拷贝取代

#endif //JSHAREDDATAPOINT_H
